package cn.com.tiza.spiro.jvm.gc.optimization;

import net.sf.cglib.beans.BeanGenerator;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;

import java.lang.reflect.Method;
import java.util.Scanner;

/**
 * Created by TZ0643 on 2016-1-21.
 */
public class Due2PermSizeFullGC {


    static class Test {
        private final static byte[] _128K = new byte[128 * 1024];

        public String hello() {
            return "hello";
        }
        public String hello1() {
            return "hello1";
        }
    }

    private static void createBeanClasses(int amount) {

        System.out.println("createBeanClasses...");

        int i = 0;
        while(true) {
            BeanGenerator generator = new BeanGenerator();
            generator.setUseCache(false);
            generator.addProperty(RandomStringUtils.random(5, "abcdefg"), String.class);
            generator.addProperty(RandomStringUtils.random(3, "hijk"), String.class);
            generator.addProperty(RandomStringUtils.random(4, "lmn"), String.class);
            generator.createClass();

            i++;
            if(i > amount) {
                break;
            }
        }
    }

    private static void createNewClasses(int amount) {

        System.out.println("createNewClasses...");

        int i = 0;
        while(true) {
            Enhancer e = new Enhancer();
            e.setUseCache(false);
            e.setSuperclass(Test.class);
            e.setCallback(new MethodInterceptor() {
                @Override
                public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
                    return proxy.invokeSuper(obj, args);
                }
            });
            e.create();

            i++;

            if(i > amount) {
                break;
            }
        }
    }

    public static void main(String[] args) throws InterruptedException {

        Scanner scanner = new Scanner(System.in);
        while(true) {
            System.out.print("INPUT -> ");
            String command = scanner.next();
            if("exit".equals(command.trim())) {

                break;
            }
            if("padd".equals(command.trim())) {
                System.out.print("INPUT amount -> ");
                String amount = scanner.next();

                if(StringUtils.isNumeric(amount)) {
                    createNewClasses(Integer.valueOf(amount));
                } else {
                    System.out.println("Argument invalid.");
                }
                continue;
            }
            if("badd".equals(command.trim())) {

                System.out.print("INPUT amount -> ");
                String amount = scanner.next();

                if(StringUtils.isNumeric(amount)) {
                    createNewClasses(Integer.valueOf(amount));
                } else {
                    System.out.println("Argument invalid.");
                }
                continue;
            }
        }
        scanner.close();
        System.out.println("exit...");
    }
}
